import {
	IParam,
	IViewAbility,
	IGlobalNotificationHelper,
	GlobalNotificationAction,
} from '@/core';

/**
 * 应用中心助手
 *
 * @export
 * @class GlobalNotificationHelper
 * @implements {IGlobalNotificationHelper}
 */
export class GlobalNotificationHelper implements IGlobalNotificationHelper {
	/**
	 * 实体-视图映射关系
	 *
	 * @private
	 * @type {Map<string, IViewAbility[]>}
	 * @memberof GlobalNotificationHelper
	 */
	private evMap: Map<string, IViewAbility[]> = new Map();

	/**
	 * 应用中心助手唯一实例
	 *
	 * @private
	 * @static
	 * @type {IGlobalNotificationHelper}
	 * @memberof GlobalNotificationHelper
	 */
	private static instance: IGlobalNotificationHelper;

	/**
	 * 其他内容标识
	 *
	 * @private
	 * @memberof GlobalNotificationHelper
	 */
	private readonly otherFlag = '$other';

	/**
	 * 获取应用中心助手实例
	 *
	 * @static
	 * @return {*}  {IGlobalNotificationHelper}
	 * @memberof GlobalNotificationHelper
	 */
	static getInstance(): IGlobalNotificationHelper {
		if (!this.instance) {
			this.instance = new GlobalNotificationHelper();
		}
		return this.instance;
	}

	/**
	 *
	 *
	 * @param {string} entity
	 * @param {string} action
	 * @param {(IParam | IParam[])} [data]
	 * @memberof GlobalNotificationHelper
	 */
	notice(
		entity: string,
		action: GlobalNotificationAction,
		data?: IParam | IParam[]
	): void {
		if (this.evMap.has(entity)) {
			const viewAbilities = this.evMap.get(entity) || [];
			viewAbilities.forEach((ability: IViewAbility) => {
				//  刷新
				if (action === 'refresh') {
					ability.refresh(data);
				}
			});
		}
	}

	/**
	 * 设置能力
	 *
	 * @param {IViewAbility} ability
	 * @memberof GlobalNotificationHelper
	 */
	setAbility(ability: IViewAbility) {
		const key = ability.getModel().entityCodeName || this.otherFlag;
		const viewAbilities = this.evMap.get(key) || [];
		if (
			viewAbilities.findIndex(
				(_ability: IViewAbility) => _ability.name !== ability.name
			) === -1
		) {
			viewAbilities.push(ability);
		}
		this.evMap.set(key, viewAbilities);
	}

	/**
	 * 销毁能力
	 *
	 * @param {IViewAbility} ability
	 * @memberof GlobalNotificationHelper
	 */
	destroyAbility(ability: IViewAbility) {
		const key = ability.getModel().entityCodeName || this.otherFlag;
		const viewAbilities = this.evMap.get(key) || [];
		const index = viewAbilities.findIndex(
			(_ability: IViewAbility) => _ability.name !== ability.name
		);
		if (index !== -1) {
			viewAbilities.splice(index, 1);
		}
		this.evMap.set(key, viewAbilities);
	}
}
